import 'package:flutter/material.dart';
import 'package:bear_story/page/home.dart';
import 'dart:ui';
import 'page/player.dart';
import 'page/settings.dart';
import 'page/book.dart';
import 'dart:convert' as convert;
import 'package:bear_story/page/login.dart';
import 'net.dart' as net;
import 'bean/beans.dart';
import 'package:flutter/services.dart';
import 'test.dart';
import 'pref.dart' as pref;

User _user;
List<Book> _collects = [];
List<Book> _historyBooks;
List<HistoryBooksUpdateListener> _historyBooksListeners = [];
List<CollectBooksListener> _collectBooksListeners = [];
List<PlayChaptersUpdateListener> _playChaptersListener = [];
List<EventChannelListener> _eventChannelListeners = [];
List<Chapter> _nowPlayChapters = [];
int _nowPlayIndex;
Book _nowPlayBook;
String _playerStatus;
double _playerProgress = 0;

int nowPlayModel = 0; //0 列表循环，1 单曲循环

const METHOD_CHANNEL = const MethodChannel("dar.flutter.io/method_channel");
const EVENT_CHANNEL = const EventChannel("dar.flutter.io/event_channel");

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  pref.getHistoryList().then((v) {
    _historyBooks = v;
  });
  pref.getNowUser().then((v) {
    _user = v;
    if (_user == null) {
      print("sUser = null");
    } else {
      print("sUser = ${_user.toJson()}");
    }
    updateNowUserCollects();
  });
  EVENT_CHANNEL.receiveBroadcastStream().listen(_onEvent);
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
//      theme: ThemeData(
//        primaryColor: Colors.white,
//        accentColor: main_theme_color,
//        highlightColor: main_theme_color
//      ),
        home: HomePage(),
//        home: TestWidget(),
        routes: {
          "/login": (BuildContext context) {
            return LoginPage();
          },
          "/settings": (BuildContext context) {
            return SettingsPage();
          },
        });
  }
}

//------------------------------------------utils
bool isEmptyList(List list) {
  if (list == null || list.length == 0) {
    return true;
  }
  return false;
}

bool isEmptyString(String str) {
  if (str == null || str.length == 0) {
    return true;
  }
  return false;
}

String avoidNullString(String s) {
  return s == null ? "" : s;
}

//------------------------------------------用户相关

Future updateNowUserLearnTime(int add) async {
  if (_user == null) {
    return;
  }
  _user.learnTime += add;
  pref.saveNowUser(_user);
  await net.updateUser(_user.objectId, {"learnTime": _user.learnTime});
}

///更新当前用户（登录/登出）
Future updateNowUser(User user) async {
  _user = user;
  pref.saveNowUser(_user);
  await updateNowUserCollects();
}

User getNowUser() {
  return _user;
}

//------------------------------------------我的收藏

///我的收藏更新通知
abstract class CollectBooksListener {
  void onCollectBooksUpdate();
}

void addCollectBooksUpdateListener(CollectBooksListener l) {
  if (!_collectBooksListeners.contains(l)) {
    _collectBooksListeners.add(l);
  }
}

void removeCollectBooksUpdateListener(CollectBooksListener l) {
  if (_collectBooksListeners.contains(l)) {
    _collectBooksListeners.remove(l);
  }
}

///获取我的收藏列表
List<Book> getNowUserCollects() {
  return _collects;
}

Future updateNowUserCollects() async {
  if (_user != null) {
    _collects = await net.getCollectBooks(_user.objectId);
  } else {
    _collects = null;
  }
  for (var v in _collectBooksListeners) {
    v.onCollectBooksUpdate();
  }
}

//------------------------------------------我的历史记录

///历史记录更新通知
abstract class HistoryBooksUpdateListener {
  void onHistoryBooksUpdate();
}

void addHistoryBooksUpdateListener(HistoryBooksUpdateListener l) {
  if (!_historyBooksListeners.contains(l)) {
    _historyBooksListeners.add(l);
  }
}

void removeHistoryBooksUpdateListener(HistoryBooksUpdateListener l) {
  if (_historyBooksListeners.contains(l)) {
    _historyBooksListeners.remove(l);
  }
}

///添加历史记录
Future addHistoryBook(Book book) async {
  if (_historyBooks == null) {
    _historyBooks = await pref.getHistoryList();
  }
  bool exist = false;
  _historyBooks.forEach((v) {
    if (v.objectId == book.objectId) {
      exist = true;
    }
  });

  if (!exist) {
    _historyBooks.add(book);
  }
  await pref.saveHistoryList(_historyBooks);

  if (!exist) {
    for (HistoryBooksUpdateListener l in _historyBooksListeners) {
      l.onHistoryBooksUpdate();
    }
  }
}

List<Book> getHistoryList() {
  return _historyBooks;
}

//------------------------------------------播放相关

///播放列表更新通知
abstract class PlayChaptersUpdateListener {
  void onPlayChaptersUpdate();
}

void addPlayChaptersUpdateListener(PlayChaptersUpdateListener l) {
  if (!_playChaptersListener.contains(l)) {
    _playChaptersListener.add(l);
  }
}

void removePlayChaptersUpdateListener(PlayChaptersUpdateListener l) {
  if (_playChaptersListener.contains(l)) {
    _playChaptersListener.remove(l);
  }
}

///获取当前播放的章节列表
List<Chapter> getNowPlayChapters() {
  return _nowPlayChapters;
}

///获取当前播放的章节列表索引
int getNowPlayIndex() {
  return _nowPlayIndex;
}

///获取当前播放的章节
Chapter getNowPlayChapter() {
  if (_nowPlayChapters == null || _nowPlayChapters.length == 0) {
    return null;
  }
  return _nowPlayChapters[_nowPlayIndex];
}

///获取当前播放的专辑
Book getNowPlayBook() {
  return _nowPlayBook;
}

///播放列表
void playList(List<Chapter> chapters, int index, Book book, bool playNow) {
  _nowPlayChapters = chapters;
  _nowPlayIndex = index;
  _nowPlayBook = book;
  _channelPlayList(_nowPlayChapters, index, playNow);
  pref.saveNowPlayBook(_nowPlayBook);
  pref.saveNowPlayIndex(_nowPlayIndex);
  for (var l in _playChaptersListener) {
    l.onPlayChaptersUpdate();
  }
}

void playSwitchToId(int id) {
  int len = _nowPlayChapters.length;
  for (int i = 0; i < len; i++) {
    if (id.toString() == _nowPlayChapters[i].objectId || id == _nowPlayChapters[i].objectId.hashCode) {
      _nowPlayIndex = i;
      pref.saveNowPlayIndex(_nowPlayIndex);
      updateNowUserLearnTime(_nowPlayChapters[i].chaptertime);
    }
  }
  try {
    for (var l in _playChaptersListener) {
      l.onPlayChaptersUpdate();
    }
  } catch (e) {
    print("playSwitchToId exception:$e");
  }
}

//------------------------------------------channel相关
Future<bool> channelUpdateBookExtra(Book book) async {
  try {
    if (!book.isBear() && !isEmptyString(book.platform) && !isEmptyString(book.platformbid)) {
      final String result = await METHOD_CHANNEL
          .invokeMethod('getAlbumJsonInfo', {"platformbid": book.platformbid, "platform": book.platform});
      print("channelUpdateBookExtra result = $result");
      book.updateFromPlatformJson(convert.jsonDecode(result));
    } else {
      print("channelUpdateBookExtra Failed platform参数不正确");
    }
    return true;
  } catch (e) {
    print("channelUpdateBookExtra exception: $e");
  }
  return false;
}

Future<List<Chapter>> channelGetChapters(Book book, int page, int pageSize) async {
  try {
    List<Chapter> chapters = [];
    if (!book.isBear() && !isEmptyString(book.platform) && !isEmptyString(book.platformbid)) {
      final String result = await METHOD_CHANNEL.invokeMethod('getChaptersJsonInfo',
          {"platformbid": book.platformbid, "platform": book.platform, "page": page, "pageSize": pageSize});
      print("channelGetChapters result = $result");
//      book.updateFromPlatformJson(convert.jsonDecode(result));
      List list = convert.jsonDecode(result);
      if (list != null) {
        for (var l in list) {
          Chapter chapter;
          if (book.platform == "xmly") {
            chapter = Chapter.fromXmlyJson(l);
          }
          if (chapter != null) {
            chapters.add(chapter);
          }
        }
      }
    } else {
      print("channelGetChapters Failed platform参数不正确");
    }
    return chapters;
  } catch (e) {
    print("channelGetChapters exception: $e");
  }
  return null;
}

Future<bool> _channelPlayList(List<Chapter> chapters, int index, bool playNow) async {
  try {
    if (chapters != null && chapters.length > index && index >= 0) {
      PlayList channelList = new PlayList();
      channelList.index = index;
      channelList.list = [];
      channelList.playModel = nowPlayModel;
      channelList.bookName = _nowPlayBook.bookname;
      for (int i = 0; i < chapters.length; i++) {
        print(chapters[i].toPlayPlatformJson(_nowPlayBook.platform));
        channelList.list.add(chapters[i].toPlayPlatformJson(_nowPlayBook.platform));
      }
      final result = await METHOD_CHANNEL.invokeMethod('playList', {
        "listData": convert.jsonEncode(channelList),
        "platform": _nowPlayBook.platform,
        "index": index,
        "playNow": playNow
      });
      print("_channelPlayList result = $result");
      return true;
    } else {
      print("_channelPlayList Failed platform参数不正确");
    }
  } catch (e) {
    print("_channelPlayList exception: $e");
  }
  return false;
}

Future<bool> channelPlayerPause() async {
  try {
    final result = await METHOD_CHANNEL.invokeMethod('playerPause', {"platform": _nowPlayBook.platform});
    print("channelPlayerPause result = $result");
    return true;
  } catch (e) {
    print("channelPlayerPause exception: $e");
  }
  return false;
}

Future<bool> channelPlayerPlay() async {
  try {
    final result = await METHOD_CHANNEL.invokeMethod('playerPlay', {"platform": _nowPlayBook.platform});
    print("channelPlayerPlay result = $result");
    return true;
  } catch (e) {
    print("channelPlayerPlay exception: $e");
  }
  return false;
}

Future<bool> channelPlayerNext() async {
  try {
    final result = await METHOD_CHANNEL.invokeMethod('playerNext', {"platform": _nowPlayBook.platform});
    print("channelPlayerNext result = $result");
    return true;
  } catch (e) {
    print("channelPlayerNext exception: $e");
  }
  return false;
}

Future<bool> channelPlayerPrev() async {
  try {
    final result = await METHOD_CHANNEL.invokeMethod('playerPrev', {"platform": _nowPlayBook.platform});
    print("channelPlayerPrev result = $result");
    return true;
  } catch (e) {
    print("channelPlayerPrev exception: $e");
  }
  return false;
}

Future<bool> channelSetPlayModel(int model) async {
  try {
    final result =
        await METHOD_CHANNEL.invokeMethod('setPlayModel', {"model": model, "platform": _nowPlayBook.platform});
    nowPlayModel = model;
    print("channelSetPlayModel result = $result");
    return true;
  } catch (e) {
    print("channelSetPlayModel exception: $e");
  }
  return false;
}

Future<bool> channelCheckNowPlayList() async {
  try {
    final result = await METHOD_CHANNEL.invokeMethod('getNowPlayList');
    print("channelGetNowPlayList result = $result");
    var nowBook = await pref.getNowPlayBook();
    if (nowBook != null) {
      _nowPlayBook = nowBook;
    }
    PlayList pList = PlayList.fromJson(convert.jsonDecode(result));
    if (pList != null && !isEmptyList(pList.list) && pList.index >= 0) {
//      nowPlayModel = pList.playModel;
      List<Chapter> list = [];
      for (var map in pList.list) {
        list.add(Chapter.fromNowPlayListJson(map));
      }
      _nowPlayChapters = list;
      _nowPlayIndex = pList.index;
      for (var l in _playChaptersListener) {
        l.onPlayChaptersUpdate();
      }
      return true;
    }
  } catch (e) {
    print("channelCheckNowPlayList exception: $e");
  }
  return false;
}

Future<bool> channelSeekToByPercent(double percent, int all) async {
  try {
    final result =
        await METHOD_CHANNEL.invokeMethod('seekToByPercent', {"percent": percent,"all":all, "platform": _nowPlayBook.platform});
    print("channelSeekToByPercent result = $result");
    return true;
  } catch (e) {
    print("channelSeekToByPercent exception: $e");
  }
  return false;
}

//------------------------------------------更新专辑的章节列表
///更新专辑的额外信息（播放量、集数等）
Future refreshBookExtraInfo(List<Book> books) async {
  if (books == null) {
    return false;
  }
  for (var book in books) {
    if (book.isBear()) {
      int playCount = await net.getBookPlayCount(book.objectId);
      int chapterCount = await net.getBookChapterCount(book.objectId);
      book.playCount = playCount;
      book.chapterCount = chapterCount;
    } else {
      await channelUpdateBookExtra(book);
    }
  }
  return true;
}

Future<List<Chapter>> getChapters(Book book, int page, int pageSize) async {
  var list;
  if (book.isBear()) {
    list = await net.getChapterByBook(book);
  } else {
    list = await channelGetChapters(book, page, pageSize);
  }
  return list;
}

//------------------------------------------接受native传来的数据
abstract class EventChannelListener {
  void onEvent(Map map);
}

void addEventChannelListener(EventChannelListener l) {
  if (!_eventChannelListeners.contains(l)) {
    _eventChannelListeners.add(l);
  }
}

void removeEventChannelListener(EventChannelListener l) {
  if (_eventChannelListeners.contains(l)) {
    _eventChannelListeners.remove(l);
  }
}

void _onEvent(event) {
//  print("onEvent  " + event);
  try {
    Map map = convert.jsonDecode(event);
    String type = map["type"];
    if (type == "player") {
      var status = map["status"];
      if (status == "onPlayProgress") {
        int now = map["now"];
        int all = map["all"];
        _playerProgress = now / all;
      } else if (status == "onPlayProgress_ios") {
        _playerProgress = map["percent"];
      } else if (status == "onBufferProgress") {
      }else {
        _playerStatus = status; //_playerStatus不包含onPlayProgress
        if (status == "onSoundSwitch") {
          int id = map["id"];
          playSwitchToId(id);
        }
      }
    }
    for (var l in _eventChannelListeners) {
      l.onEvent(map);
    }
  } catch (e) {
    print("_onEvent exception:$e");
  }
}

bool isPlaying() {
  final playingStatus = [
    "onStartPlayAds",
    "onCompletePlayAds",
    "onPlayStart",
    "onSoundPrepared",
//    "onPlayProgress",
    "onBufferingStart",
    "onBufferingStop",
//    "onBufferProgress"
  ];
  if (playingStatus.contains(_playerStatus)) {
    return true;
  }
  return false;
}

double getPlayerProgress() {
  return _playerProgress;
}
